import App from '../../examples/files/app/networking'
import posts from '../../examples/files/app/posts'

## APIs

`Networking` in React Native is built on two APIs: `fetch` and `XMLHttpRequest`. Both of these were designed to be compatible with browser APIs so that:

- Web developers don't have to learn a new way to make network requests
- Libraries built on top of these function as expected in React Native

It's common to use the `fetch` API directly, since it's fairly powerful and high-level. It's rare to use XMLHttpRequest directly, since it's complex and low-level. If your networking needs are advanced (multi-part form requests, etc), you'll likely want to use a library that abstracts the details of these networking APIs.

If you're looking for an abstraction layer, browser/node networking libraries like `axios` and `superagent` will still work in React Native.

## Fetch API

Let's take a look at `fetch`, since it's powerful and comes with React Native out of the box. The Fetch API is promise-based, meaning we can use `async/await`.

### **`const response = await fetch(uri)`**

Send a `GET` request to `uri`, returning a promise which represents a `Response` object. To access the data returned, you must either await `response.text()` or `response.json()`.

### **`const json = await response.json()`**

Parse the body of the response asynchronously as JSON.

### **`const text = await response.text()`**

Get the body of the response as text.

### That's it!

We can get started using `fetch` with just that! If you want to use fetch with custom request headers or for `POST` requests, read more about the API [here at MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch).

## Example

Here we'll fetch a list of posts and display them in a FlatList. Since `fetch` is asynchronous, our app won't have data to show right when it loads. We should instead show a loading state, e.g. an `ActivityIndicator` (spinner), while data loads. We should also be prepared to show an error message if fetching data fails.

This example uses [`useReducer` for managing data](/app/data_management/usereducer).

_Note: fetch may not work if you're using an older browser._

<Example
  files={{
    'App.js': App,
    'posts.js': posts,
  }}
/>
